home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
tppop18c.arc
/
POPUP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-28
|
5KB
|
154 lines
{$A+,B-,D+,E+,F-,I+,L+,N+,O-,R-,S-,V-}
Unit PopUp;
Interface
Uses Dos,Crt;
Const
RightShift = $0100; { right shift key }
LeftShift = $0200; { left shift key }
Control = $0400; { control key }
ALT = $0800; { ALT key }
Function Installed(OurID : Byte) : Byte;
Procedure StayResident(OurID : Byte;Vector,HaltPtr : Pointer;PopKey : Word);
Procedure ReleaseEnvironment; { releases the environment memory }
Implementation
Var
ProgramVector : Pointer; { address of popup program }
HaltVector : Pointer; { address of exit routine }
oldDTA : Pointer; { interrupted DTA }
OurDTA : Pointer; { our DTA }
PrevBreak : Boolean; { previous BREAK status }
EnvReleased : Boolean;
Procedure ReleaseBlock(Segment : Word);
{ Given a segment, releases the memory. }
InLine($07/ { pop es }
$B4/$49/ { mov ah,49h }
$CD/$21); { int 21h }
Procedure ReleaseEnvironment;
{ Releases the memory of the environment segment. }
Begin
If Not EnvReleased Then
Begin
ReleaseBlock(MemW[PrefixSeg:$002C]); { free the enviornment }
EnvReleased := True;
End;
End;
Function GetBreakStatus : Boolean;
InLine($B8/$00/$33/ { mov ax,3300h }
$CD/$21/ { int 21h }
$88/$D0); { mov al,dl }
Procedure SetBreakStatus(Status : Boolean);
InLine($5A/ { pop dx }
$B8/$01/$33/ { mov ax,3301h }
$CD/$21); { int 21h }
Function GetDTAVec : Pointer;
{ returns the segment:offset of the DTA }
InLine($B4/$2F/ { mov ah,2Fh }
$CD/$21/ { int 21h }
$89/$D8/ { mov ax,bx }
$8C/$C2); { mov dx,es }
Procedure SetDTAVec(DTA : Pointer);
{ sets the segment:offset of the DTA }
InLine($8C/$D8/ { mov ax,ds }
$5A/ { pop dx }
$1F/ { pop ds }
$50/ { push ax }
$B4/$1A/ { mov ah,1Ah }
$CD/$21/ { int 21h }
$1F); { pop ds }
Procedure EntryInit;
Begin
PrevBreak := GetBreakStatus; { save the BREAK status flag }
SetBreakStatus(False); { turn of BREAK }
OldDTA := GetDTAVec; { get the current DTA address }
SetDTAVec(OurDTA); { set it to our own address }
SwapVectors; { install our interrupt vectors }
End;
Procedure EntryExit;
Begin
SwapVectors; { restore the interrupt vectors }
SetDTAVec(OldDTA); { restore the DTA address }
SetBreakStatus(PrevBreak); { restore the original BREAKing status }
End;
Procedure ReleaseProgram; Interrupt;
{ Releases the program's memory. We call this when unhooking the program. }
Begin
If HaltVector <> Nil Then
Begin
EntryInit;
InLine($FF/$1E/>HaltVector);
EntryExit;
End;
ReleaseBlock(PrefixSeg);
ReleaseEnvironment;
End;
Procedure CriticalHandler; External; {$L crit.obj}
{ internal routine - don't ever call direct }
Procedure CallPopUp; Interrupt;
{ set some interrupt vectors and run the popup progams }
{ restore the interrupt vectors when done }
Begin
EntryInit;
InLine($FF/$1E/>ProgramVector); { call the user's procedure }
EntryExit;
End;
Function Installed(OurID : Byte) : Byte; External;
Procedure InitializePopUp(OurID : Byte;PopKey : Word); External;
{ sets interrupt vectors }
{$L popup.obj}
Procedure StayResident(OurID : Byte;Vector,HaltPtr : Pointer;PopKey : Word);
{ saves some info and Terminated and Stays Resident }
Begin
OurDTA := GetDTAVec; { save our DTA address }
SetIntVec($23,@CriticalHandler); { install our critical error handler }
SwapVectors; { restore all the vectors, save ours }
ProgramVector := Vector; { save the user program address }
HaltVector := HaltPtr; { Our exit routine }
InitializePopUp(OurID,PopKey); { install our interrupt vectors }
Keep(0); { terminate and stay resident }
End;
Begin
CheckBreak := False; { ignore the control break key }
EnvReleased := False; { environment not yet released }
End.